package com.raycloud.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 
 * <p>
 * Title: DateUtil.java
 * </p>
 * <p>
 * Description: 一些日期的工具方法,时间格式全部为二十四小时制
 * </p>
 * 
 */
public class DateUtil {
	// //////////////////////////////////////////////////////////
	// /以下是将日期转换成字符串的方法
	/**
	 * 返回当前的时间 yyyy-MM-dd HH:mm:ss
	 * 
	 * @return
	 */
	public static String getNowDateTime() {
		return DateFormateFactory.getS("datetime").format(new Date());
	}

	/**
	 * 将传入的日期转换成 yyyy-MM-dd HH:mm:ss的形式
	 * 
	 * @param date
	 * @return
	 */
	public static String getDateTime(Date date) {
		return DateFormateFactory.getS("datetime").format(date);
	}

	/**
	 * 将传入的long转换成 yyyy-MM-dd HH:mm:ss的形式
	 * 
	 * @param time
	 * @return
	 */
	public static String getDateTime(long time) {
		return DateFormateFactory.getS("datetime").format(time);
	}

	/**
	 * 返回当前日期 yyyy-MM-dd
	 * 
	 * @return
	 */
	public static String getNowDate() {
		return DateFormateFactory.getS("date").format(new Date());
	}

	/**
	 * 将传入的日期转换成 yyyy-MM-dd的形式
	 * 
	 * @param date
	 * @return
	 */
	public static String getDate(Date date) {
		return DateFormateFactory.getS("date").format(date);
	}

	/**
	 * 将传入的long转换成 yyyy-MM-dd的形式
	 * 
	 * @param date
	 * @return
	 */
	public static String getDate(long time) {
		return DateFormateFactory.getS("date").format(time);
	}

	/**
	 * 返回当前的年月 yyyy-MM
	 * 
	 * @return
	 */
	public static String getNowYearMonth() {
		return DateFormateFactory.getS("yearmonth").format(new Date());
	}

	/**
	 * 将传入的日期转换成 yyyy-MM形式
	 * 
	 * @param date
	 * @return
	 */
	public static String getYearMonth(Date date) {
		return DateFormateFactory.getS("yearmonth").format(date);
	}

	/**
	 * 将传入的long转换成 yyyy-MM形式
	 * 
	 * @param date
	 * @return
	 */
	public static String getYearMonth(long time) {
		return DateFormateFactory.getS("yearmonth").format(time);
	}

	/**
	 * 得到程序员自定义格式的当前时间字符串
	 * 
	 * @param pattern
	 * @return
	 * @throws IllegalArgumentException
	 *             如果输入的pattern不正确
	 */
	public static String getNowByPattern(String pattern)
			throws IllegalArgumentException {
		try {
			return new SimpleDateFormat(pattern).format(new Date());
		} catch (IllegalArgumentException e) {
			throw new IllegalArgumentException("输入参数不正确", e);
		}
	}

	/**
	 * 得到程序员自定义格式的特定时间字符串
	 * 
	 * @param pattern
	 * @param date
	 * @return
	 * @throws IllegalArgumentException
	 *             如果输入的pattern不正确
	 */
	public static String getByPattern(String pattern, Date date)
			throws IllegalArgumentException {
		try {
			return new SimpleDateFormat(pattern).format(date);
		} catch (IllegalArgumentException e) {
			throw new IllegalArgumentException("输入参数不正确", e);
		}
	}

	/**
	 * 得到程序员自定义格式的特定long时间的字符串
	 * 
	 * @param pattern
	 * @param date
	 * @return
	 * @throws IllegalArgumentException
	 *             如果输入的pattern不正确
	 */
	public static String getByPattern(String pattern, long time)
			throws IllegalArgumentException {
		try {
			return new SimpleDateFormat(pattern).format(time);
		} catch (IllegalArgumentException e) {
			throw new IllegalArgumentException("输入参数不正确", e);
		}
	}

	// /////////////////////////////////////////////////////
	// 以下是将字符串转换成日期的方法,一般用于解析界面上传入的日期数据
	/**
	 * 将格式为 yyyy-MM-dd 形式的字符串转换成日期
	 */
	public static Date parseDate(String sourse) throws Exception {
		try {
			return DateFormateFactory.getS("date").parse(sourse);
		} catch (ParseException e) {
			throw new Exception("期待 yyyy-MM-dd 格式的日期,但输入格式为: " + sourse, e);
		}
	}

	/**
	 * 将格式为 yyyy-MM-dd HH:mm:ss 的字符串转换成日期
	 * 
	 * @param sourse
	 * @return
	 * @throws Exception
	 */
	public static Date parseDateTime(String sourse) throws Exception {
		try {
			return DateFormateFactory.getS("datetime").parse(sourse);
		} catch (ParseException e) {
			throw new Exception("期待 yyyy-MM-dd HH:mm:ss  格式的日期,但输入格式为: "
					+ sourse, e);
		}
	}

	/**
	 * 得到用户的时间分割
	 * 
	 * @param date
	 * @return
	 */
	public static String getUserDateSplit(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		String dateStr = getByPattern("yyyy-MM", date);
		int day = c.get(Calendar.DAY_OF_MONTH);
		return dateStr + (day / 10);
	}

	/**
	 * 得到与传入时间date，在字段offsetField上相差offset的date
	 * 
	 * @param date
	 * @param offset
	 * @param offsetField
	 *            Calendar类的field
	 * @return
	 */
	public static Date getDistanceDate(Date date, int offset, int offsetField) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(offsetField, c.get(offsetField) + offset);
		return c.getTime();
	}

	/**
	 * 将传入的时间间隔(毫秒)转换成 xx天xx小时xx分xx秒的形式
	 * 
	 * @param distance
	 * @return
	 * @deprecated 因为暂时没有实现,所以就不推荐使用了 ^.^
	 */
	public static String getDistance(long distance) {

		return null;
	}

	/**
	 * 展示date距离当前时间信息，比如10分钟前，今天16：10等
	 * 
	 * @param date
	 * @return
	 */
	public static String showOffsetDate(Date date) {
		long now = System.currentTimeMillis();
		long dateL = date.getTime();
		long offset = now - dateL;
		if (offset < 0) {
			return "";
		}

		long offsetMin = offset / (1000 * 60);
		if (offsetMin < 60) {
			if(offsetMin == 0) {
				return "刚刚";
			}
			return offsetMin + "分钟前";
		} else {
			long offsetHour = offsetMin / 60;
			Calendar c = Calendar.getInstance();
			c.setTime(date);
			if (offsetHour < 24) {
				return "今天" + c.get(Calendar.HOUR_OF_DAY) + ":"
						+ c.get(Calendar.MINUTE);
			} else {
				return (c.get(Calendar.MONTH) + 1) + "月"
						+ c.get(Calendar.DAY_OF_MONTH) + "日 "
						+ c.get(Calendar.HOUR_OF_DAY) + ":"
						+ c.get(Calendar.MINUTE);
			}
		}
	}
}

class DateFormateFactory {
	private static Map<String, SimpleDateFormat> map = new HashMap<String, SimpleDateFormat>();

	static {
		map.put("datetime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
		map.put("date", new SimpleDateFormat("yyyy-MM-dd"));
		map.put("yearmonth", new SimpleDateFormat("yyyy-MM"));
	}

	protected static SimpleDateFormat getS(String formate) {
		return map.get(formate);
	}

}